package com.xdl.modules.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.beluga.core.BPay;
import com.beluga.core.annotation.BLimit;
import com.beluga.core.annotation.BelugaController;
import com.beluga.core.model.wechat.WxPayOrderNotifyResult;
import com.beluga.core.notify.WxPayNotifyResponse;
import com.beluga.core.notify.WxPayRefundNotifyResult;
import com.beluga.core.response.ResponseResult;
import com.beluga.core.util.DateUtil;
import com.beluga.core.util.Func;
import com.beluga.notice.sms.SMSClient;
import com.beluga.notice.sms.SMSEntity;
import com.xdl.common.utils.RedisUtils;
import com.xdl.modules.constant.OrderEnum;
import com.xdl.modules.dto.WxActivityDto;
import com.xdl.modules.dto.WxOrderDto;
import com.xdl.modules.dto.WxOrderToken;
import com.xdl.modules.entity.SysAnnouncement;
import com.xdl.modules.entity.WxOrderDetail;
import com.xdl.modules.model.OrderModel;
import com.xdl.modules.model.WxOrderModel;
import com.xdl.modules.service.SysAnnouncementService;
import com.xdl.modules.service.WxActivityDetailService;
import com.xdl.modules.service.WxOrderDetailService;
import com.xdl.modules.util.WxWorkApi;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author iron guo
 * @since 2022-04-30
 */
@AllArgsConstructor
@BelugaController("/wx/order")
public class WxOrderDetailController {

    private WxOrderDetailService orderService;

    /**
     * 统一支付平台
     */
    private BPay bPay;

    private RedisUtils cache;

    private SMSClient smsClient;

    private WxActivityDetailService detailService;

    private SysAnnouncementService announcementService;

    private WxWorkApi wxWorkApi;

    /**
     * 微信下单活动 保存订单
     *
     * @param model
     * @return
     */
    @PostMapping("order")
    @BLimit(value = "order", limit = 20)
    public ResponseResult<?> order(@RequestBody OrderModel model) {
        WxOrderDetail order = new WxOrderDetail();
        Func.copy(model, order);
        WxOrderToken result = orderService.order(order);
        return ResponseResult.Success(result);
    }

    /**
     * 取消订单
     * @param id
     * @return
     */
    @GetMapping("cancelOrder")
    @BLimit(value = "cancelOrder", limit = 20)
    public ResponseResult<?> cancelOrder(@RequestParam Long id) {
        String cancel=orderService.cancelOrder(id);
        return ResponseResult.Success(cancel);
    }

    /**
     * 支付订单
     * @param orderSn
     * @return
     */
    @GetMapping("payOrder")
    public ResponseResult<?> payOrder(@RequestParam String orderSn ) {
        Map<Object,Object> pay=orderService.payOrder(orderSn);
        return ResponseResult.Success(pay);
    }

    /**
     * 删除订单&关闭订单
     * @param id
     * @return
     */
    @GetMapping("removeOrder")
    public ResponseResult<?> removeOrder(@RequestParam Long id ) {
        WxOrderDetail detail = orderService.getById(id);
        if(detail.getStatus().equals(OrderEnum.STAY_BPAY)){
            //关闭订单
            bPay.closeWxOrder(detail.getOrderSn());
        }
        orderService.removeById(id);
        return ResponseResult.Success();
    }



    /**
     * 关闭订单
     * @param id
     * @return
     */
    @GetMapping("closeOrder")
    @BLimit(value = "closeOrder", limit = 20)
    public ResponseResult<?> closeOrder(@RequestParam Long id) {
        String close=orderService.closeOrder(id);
        return ResponseResult.Success(close);
    }


    /**
     * 获取订单列表
     * @param model
     * @return
     */
    @PostMapping("getOrderList")
    @BLimit(value = "orderList", limit = 20)
    public ResponseResult<?> getOrderList(@RequestBody WxOrderModel model) {
        IPage<WxOrderDto> result = orderService.getOrderList(model);
        return ResponseResult.Success(result);
    }





    /**
     * 支付回调通知处理
     * @param xmlData
     * @return
     */
    @PostMapping("callback")
    public String callback(@RequestBody String xmlData){
        WxPayOrderNotifyResult result=WxPayOrderNotifyResult.fromXML(xmlData);
        QueryWrapper<WxOrderDetail> wrapper=new QueryWrapper<>();
        wrapper.lambda().eq(WxOrderDetail::getOrderSn,result.getOutTradeNo());
        WxOrderDetail detail = orderService.getOne(wrapper);
        if(Func.isEmpty(detail.getOrderSn())){
            return WxPayNotifyResponse.fail("订单不存在");
        }
        detail.setPayStatus(OrderEnum.IS_PAY).setStatus(OrderEnum.IS_BPAY);
        detail.setTransactionId(result.getTransactionId());
        orderService.updateById(detail);
        /**
         * 删除redis支付令牌
         *
         */
        String key = "XDLORDER_" + detail.getOrderSn();
        cache.del(key);
        /**
         * 发送短信提示
         */
        WxActivityDto act = detailService.getActById(detail.getActId());
        HashMap<String, Object> param = new HashMap<>();
        param.put("name", detail.getName());
        param.put("time", DateUtil.format(detail.getAppointTime(),DateUtil.PATTERN_DATE));
        param.put("activity", act.getTitle());
        param.put("address",act.getAddress());
        param.put("shop",act.getShopName());
        SMSEntity params=new SMSEntity();
        params.setPhone(detail.getPhone());
        params.setSignName("新动力");
        params.setTemplateCode("SMS_241357479");
        params.setSmsParams(param);
        smsClient.sendSMS(params);
        /**
         * 发送系统信息
         */
        String msg = "%s 先生/女士：已成功预约 %s 于 %s 的 %s 活动，请关注！<a href=\"http://admin.xin-dl.com\">点击查看详情</a>";
        msg = String.format(msg,detail.getName(),DateUtil.format(detail.getAppointTime(), DateUtil.PATTERN_DATE), act.getShopName(), act.getTitle());
        SysAnnouncement announcement = new SysAnnouncement();
        announcement.setTitile("新订单通知！");
        announcement.setMsgContent(msg);
        announcement.setPriority("M");
        announcementService.save(announcement);
        /**
         * 发送企业微信信息
         */
        wxWorkApi.sendWxWorkOffer(msg);
        return WxPayNotifyResponse.success("回调成功！");
    }

    /**
     * 退款回调通知处理
     * @param xmlData
     * @return
     */
    @PostMapping("refundCallback")
    public String refundCallback(@RequestBody String xmlData){
        WxPayRefundNotifyResult notifyResult = bPay.parseWxRefundNotifyResult(xmlData);
        QueryWrapper<WxOrderDetail> wrapper=new QueryWrapper<>();
        wrapper.lambda().eq(WxOrderDetail::getOrderSn,notifyResult.getReqInfo().getOutTradeNo());
        WxOrderDetail detail = orderService.getOne(wrapper);
        if(Func.isEmpty(detail.getOrderSn())){
            return WxPayNotifyResponse.fail("订单不存在");
        }
        detail.setPayStatus(OrderEnum.REFUND).setStatus(OrderEnum.AFTER_SALE);
        orderService.updateById(detail);
        /**
         * 发送短信提示
         */
        WxActivityDto act = detailService.getActById(detail.getActId());
        HashMap<String, Object> param = new HashMap<>();
        param.put("name", detail.getName());
        param.put("time", DateUtil.format(detail.getAppointTime(),DateUtil.PATTERN_DATE));
        param.put("activity", act.getTitle());
        param.put("shop",act.getShopName());
        SMSEntity params=new SMSEntity();
        params.setPhone(detail.getPhone());
        params.setSignName("新动力");
        params.setTemplateCode("SMS_241347432");
        params.setSmsParams(param);
        smsClient.sendSMS(params);
        return WxPayNotifyResponse.success("成功");
    }

}
